package com.jiujichaoshi.oauth.server.config;

import com.jiujichaoshi.oauth.server.security.ExtendJwtAccessTokenConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.token.AccessTokenConverter;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

/**
 * Description: JWT认证Bean配置
 *
 * @author YangLong [410357434@163.com]
 * @version V1.0
 * @date 2021/2/4
 */
@SuppressWarnings("deprecation")
@Configuration
public class JwtAuthenticationConfig {
    @Autowired
    private JwtProperties jwtProperties;
    @Autowired
    private ClientDetailsService clientDetailsService;

    /**
     * 设置JWT token store。
     *
     * @param accessTokenConverter
     * @return
     */
    @Bean
    public TokenStore tokenStore(JwtAccessTokenConverter accessTokenConverter) {
        return new JwtTokenStore(accessTokenConverter);
    }

    /**
     * JWT token生成，解释器
     *
     * @return JwtAccessTokenConverter
     */
    @Bean
    public ExtendJwtAccessTokenConverter accessTokenConverter() {
        ExtendJwtAccessTokenConverter converter = new ExtendJwtAccessTokenConverter();
        converter.setSigningKey(jwtProperties.getRsaKey());
        return converter;
    }

    /**
     * token service,JWT需要使用，在刷新token时。
     *
     * @param tokenStore tokenStore
     * @return DefaultTokenServices
     */
    @Bean
    @Primary
    public DefaultTokenServices tokenServices(TokenStore tokenStore, AccessTokenConverter accessTokenConverter) {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore);
        //这里可以自定义tokenEnhancer，添加自定义信息到JWT中
        defaultTokenServices.setTokenEnhancer((TokenEnhancer) accessTokenConverter);
        defaultTokenServices.setClientDetailsService(clientDetailsService);
        defaultTokenServices.setSupportRefreshToken(true);
        //refreshToken过期时间
        defaultTokenServices.setRefreshTokenValiditySeconds(jwtProperties.getRefreshTokenExpire());
        //Token过期时间
        defaultTokenServices.setAccessTokenValiditySeconds(jwtProperties.getTokenExpire());
        return defaultTokenServices;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }

    /**
     * 自定义authenticationManager
     *
     * @return AuthenticationManager
     */
//    @Bean
//    public AuthenticationManager authenticationManager(PasswordEncoder passwordEncoder) {
//        List<AuthenticationProvider> providers = new ArrayList<>();
//        providers.add(new SmsAuthenticationProvider(smsCaptchaFindService, userDetailsService));
//        providers.add(daoAuthenticationProvider(passwordEncoder));
//        providers.add(preAuthenticatedAuthenticationProvider());
//        return new ProviderManager(providers);
//    }

    /**
     * 自定义DaoAuthenticationProvider用于用户名密码登录
     *
     * @return DaoAuthenticationProvider
     */
//    private AuthenticationProvider daoAuthenticationProvider(PasswordEncoder passwordEncoder) {
//        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
//        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder);
//        daoAuthenticationProvider.setUserDetailsService(userDetailsService);
//        return daoAuthenticationProvider;
//    }

    /**
     * 自定义 PreAuthenticatedAuthenticationProvider,用于refresh token认证
     *
     * @return PreAuthenticatedAuthenticationProvider
     */
//    private PreAuthenticatedAuthenticationProvider preAuthenticatedAuthenticationProvider() {
//        PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
//        provider.setPreAuthenticatedUserDetailsService(new UserDetailsByNameServiceWrapper<>(userDetailsService));
//        return provider;
//    }
}
